<?php

namespace app\common\model;

use app\common\util\ImageHelper;
use RuntimeException;
use think\Model;

/**
 * @property int $id ID
 * @property int $type_id 题目类型ID
 * @property Type $question_type 题目类型
 * @property int $author_id 作者用户ID
 * @property User $author 作者
 * @property int $style 0选择，1填空
 * @property string $image 图片文件名
 * @property string $image_url 图片URL
 * @property string $image_path 图片物理路径
 * @property string $text 题干
 * @property array $options 选项
 * @property string $answer 答案
 * @property int $status 题目状态，0未审核，1通过，2不通过
 * @property int $pass_count 做对次数
 * @property int $fail_count 做错次数
 * @property bool $is_exported 是否已经导出
 * @property string $create_at 创建时间
 * @property string $update_at 更新时间
 */
class Question extends Model
{
    // 数据表名
    protected $table = 'questions';
    // 主键
    protected $pk = 'id';
    // 保存时自动补完
    protected $auto = [];
    // 新增时自动补完
    protected $insert = [];
    // 更新时自动补完
    protected $update = [];
    // 创建时间字段
    protected $createTime = 'create_at';
    // 更新时间字段
    protected $updateTime = 'update_at';
    // 是否需要自动写入时间戳
    protected $autoWriteTimestamp = true;
    // 类型声明
    protected $type = [
        'id'          => 'integer',
        'type_id'     => 'integer',
        'author_id'   => 'integer',
        'style'       => 'integer',
        'image'       => 'string',
        'text'        => 'string',
        // 'options'     => 'json',
        'answer'      => 'string',
        'status'      => 'int',
        'pass_count'  => 'int',
        'fail_count'  => 'int',
        'is_exported' => 'boolean',
        'create_at'   => 'datetime',
        'update_at'   => 'datetime',
    ];
    // JSON数据表字段
    protected $json = ['options'];
    // JSON数据取出是否需要转换为数组
    protected $jsonAssoc = true;

    // 附加字段
    protected $append = ['image_url'];
    // 隐藏字段
    protected $hidden = ['image_path'];

    protected $imageDir = 'image';

    /**
     * image_url属性
     */
    public function getImageUrlAttr()
    {
        if ($this->image) {
            return ImageHelper::urlRoot($this->imageDir) . $this->image;
        } else {
            return null;
        }
    }

    /**
     * image_path属性
     */
    public function getImagePathAttr()
    {
        if ($this->image) {
            return ImageHelper::pathRoot($this->imageDir) . $this->image;
        } else {
            return null;
        }
    }

    /**
     * 构建image属性值
     */
    public function buildImageName($ext)
    {
        return ImageHelper::buildUnusedName('G[id:4].[time:Ymd_His]_[rand:6].[ext]', [
            'id' => $this->id,
            'ext' => $ext,
            'dir' => $this->imageDir
        ]);
    }

    /**
     * 当图片存在时删除图片
     */
    public function removeImageIfExist()
    {
        $imagePath = $this->image_path;
        if ($imagePath && file_exists($imagePath)) {
            @unlink($imagePath);
        }
    }

    /**
     * 判断给定的用户是否是此题目的作者
     */
    public function isAuthor(User $user)
    {
        return $this->author_id === $user->id;
    }

    /**
     * 更新pass_count和fail_count
     */
    public function updateExamCount()
    {
        $pass_count = QuestionExam::where('question_id', 1)->where('result', 1)->count();
        $fail_count = QuestionExam::where('question_id', 1)->where('result', 2)->count();
        $this->pass_count = $pass_count;
        $this->fail_count = $fail_count;
        $this->save();
    }

    /**
     * 定义数据类型属性question_type
     */
    public function questionType()
    {
        // 当前模型的arg[2]字段=arg[1]模型的主键
        return $this->belongsTo('\app\common\model\Type', 'type_id');
    }

    /**
     * 定义数据类型属性author
     */
    public function author()
    {
        // 当前模型的arg[2]字段=arg[1]模型的主键
        return $this->belongsTo('\app\common\model\User', 'author_id');
    }

    /**
     * 转为智力方舟答题系统的文本格式
     *
     * @return string
     */
    public function buildArkDescription()
    {
        $pass = $this->pass_count;
        $check = $this->fail_count;
        $total = $pass + $check;
        $options = $this->options;

        $result = '';
        // 题目第一行
        $result .= $this->id; // 题目ID
        $result .= ' ';
        $result .= $this->question_type->output_code; // 题目类型编号，由output_code输出编号指定
        $result .= ' ';
        $result .= $this->style; // 题目形式，style
        $result .= ' ';
        $result .= \preg_replace('/\.\w+$/', '', $this->image ?: '0.jpg'); // 图片名称，即文件名不要后缀名，输出时有G开头，0表示没有图片
        $result .= ' ';

        $result .= $total > 0 ? ($pass / $total) : 0;
        $result .= "\n";
        // 题目第二行
        $result .= $this->text;

        if ($this->style === 0) {
            foreach ($options as $opt) {
                $result .= ' ' . $opt;
            }
        }
        $result .= "\n";
        // 题目第三行
        $result .= $this->answer;
        $result .= "\n";
        return $result;
    }

    /**
     * 转换为抢答题描述文本
     * QRQ = quick response question
     */
    public function buildQRQDescription()
    {
        static $i = 0;
        $i++;
        if ($this->image !== null) {
            throw new RuntimeException('图片题不能作为抢答题');
        }

        $pass = $this->pass_count;
        $check = $this->fail_count;
        $total = $pass + $check;
        $passRate = $total > 0 ? ($pass / $total) : 0;
        $passRate = round($passRate, 2);

        $typeName = $this->question_type->root_type->type_name;

        $result = $i . '.' . "\n";
        $result .= '#' . $this->id . ' '
            . '题目类型：' . $typeName . ' '
            . '正确率：' . $passRate . "%\n";
        $result .= ($this->style === 0) ? '(选择题) ' : '(填空题) ';
        $result .= $this->text . "\n";

        if ($this->style === 0) {
            foreach ($this->options as $k => $opt) {
                $result .= chr(65 + $k) . '.' . $opt . ' ';
            }
        }

        $result .= "\n";
        $result .= '答案：' . $this->answer . "\n";

        return $result;
    }
}
